/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.claro.administracionSolicitudes.beans;

import co.com.claro.administracionSolicitudes.dao.exceptions.ClaroException;
import co.com.claro.administracionSolicitudes.db.EJBDatabaseSolicitudesLocal;
import co.com.claro.administracionSolicitudes.ejb.EJBAdminSolicitudesLocal;
import co.com.claro.administracionSolicitudes.entity.Cargo;
import co.com.claro.administracionSolicitudes.entity.Ciudad;
import co.com.claro.administracionSolicitudes.entity.Empresa;
import co.com.claro.administracionSolicitudes.entity.Gerencia;
import co.com.claro.administracionSolicitudes.entity.Grupo;
import co.com.claro.administracionSolicitudes.entity.TipoDocumento;
import co.com.claro.administracionSolicitudes.entity.TipoEmpleado;
import co.com.claro.administracionSolicitudes.entity.Usuario;
import co.com.claro.administracionSolicitudes.entity.enums.EstadoActividadEnum;
import co.com.claro.administracionSolicitudes.entity.enums.TipoEmpleadoEnum;
import co.com.claro.administracionSolicitudes.seguridad.EJBSeguridadLocal;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;

/**
 *
 * @author Mike
 */
@ManagedBean
@ViewScoped
public class CrearUsuarioBean {

    @EJB
    private EJBAdminSolicitudesLocal localAdminSol;
    @EJB
    private EJBDatabaseSolicitudesLocal localDatabase;
    @EJB
    private EJBSeguridadLocal localSeguridad;

    /**
     * Constante que define la expresión regular para validar los correos
     * electrónicos
     */
    private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
            + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

    /**
     * Constante que contiene el id de la base de datos de la aplicación admin
     * solicitudes
     */
    private final int idAdminSolicitudes = 1;
    /**
     * Lista que contiene los tipos de empleados (CAMBIAR A ENUM)
     */
    private List<SelectItem> tipoEmpleadosSelect;
    /**
     * Lista que contiene los tipos de documentos (CAMBIAR A ENUM)
     */
    private List<SelectItem> tipoDocumentoSelect;
    /**
     * Lista que contiene las diferentes áreas disponibles para los usuarios
     */
    private List<SelectItem> gerenciasSelect;
    /**
     * Lista de las ciudades donde se creará el usuario
     */
    private List<SelectItem> ciudadesSelect;
    /**
     * Lista con las compañías a las que puede pertenecer el usuario
     */
    private List<SelectItem> companiasSelect;
    /**
     * Lista de cargos para el usuario
     */
    private List<SelectItem> cargosSelect;
    /**
     * Lista con los diferentes grupos (roles) disponibles en el sistema
     */
    private List<SelectItem> gruposSelect;
    /**
     * Variable que contiene el tipo de empleado seleccionado por el usuario
     */
    private String tipoEmpleadoSeleccionado;
    /**
     * Variable que contiene el tipo de documento seleccionado por el usuario
     */
    private String tipoDocumentoSeleccionado;
    /**
     * Variable que contiene la gerencia a la que pertenece el usuario
     */
    private String gerenciaSeleccionado;
    /**
     * Variable que contiene la ciudad a la que pertenece el usuario
     */
    private String ciudadSeleccionado;
    /**
     * Variable que contiene el cargo del usuario
     */
    private String cargoSeleccionado;
    /**
     * Variable que contiene el(los) nombre(s) del usuario
     */
    private String nombresUsuario;
    /**
     * Variable que contiene el(los) apellido(s) del usuario
     */
    private String apellidosUsuario;
    /**
     * Variable que contiene el número del documento del usuario
     */
    private Integer numeroDocumentoUsuario;
    /**
     * Variable que contiene la compañía a la que pertenece el usuario
     */
    private String companiaSeleccionado;
    /**
     * Variable que contiene el correo electrónico del usuario
     */
    private String correoUsuario;
    /**
     * Variable que contiene el grupo (rol) al que pertenecerá el usuario
     */
    private String grupoSeleccionado;
    /**
     * Variable que contiene el teléfono del usuario
     */
    private String telefono;
    /**
     * Variable que contiene la extensión del usuario
     */
    private String extension;
    /**
     * Variable que contiene el teléfono personal del usuario
     */
    private String telefonoPersonal;
    /**
     * Variable para saber si el usuario tiene usuario de red o no
     */
    private String tieneUsuarioRed;
    /**
     * Variable que contiene el username que el usuario ingresa
     */
    private String usernameUsuario;
    /**
     * Variable que controla si se muestra el textbox de username
     */
    private boolean mostrarUsername;
    /**
     * Variable que controla si se muestra el radio button de usuario de red
     */
    private boolean mostrarUsuarioRed;
    /**
     * Variable que contiene los mensajes de confirmación o error que se le
     * muestran al usuario en el popup
     */
    private String mensaje;

    /**
     * Creates a new instance of CrearUsuarioBean
     */
    public CrearUsuarioBean() {
    }

    @PostConstruct
    public void inicializar() {
        mostrarUsername = true;
        llenarTipoEmpleados();
        llenarTipoDocumentos();
        llenarAreas();
        llenarCiudades();
        llenarCargos();
        llenarCompanias();
        llenarGrupos();
    }

    //++++++++++++++++++++++++++++++++ EVENTOS PROPIOS DEL BEAN ++++++++++++++++++++++++
    /**
     * Método para activar/inactivar el campo de username
     */
    public void activarUsername() {
        if (tieneUsuarioRed.equals("1")) {
            mostrarUsername = true;
        } else {
            mostrarUsername = false;
        }
    }

    /**
     * Método para activar/inactivar el select one que pregunta al ususario si
     * tiene usuario de red o no
     */
    public void activarUsuarioRed() {
        if (tipoEmpleadoSeleccionado.equals("1")) {
            mostrarUsuarioRed = false;
            mostrarUsername = true;
            tieneUsuarioRed = "1";
        } else {
            mostrarUsuarioRed = true;
            mostrarUsername = false;
            tieneUsuarioRed = null;
        }
    }

    /**
     * Método que envía el objeto al EJB para que lo persista en la base de
     * datos
     */
    public void crearUsuario() {
        if (isCamposInvalidos()) {
            return;
        }

        List<Grupo> grupos = new ArrayList<Grupo>();

        grupos.add(new Grupo(Short.parseShort(grupoSeleccionado)));

        Usuario usuario = new Usuario();
        usuario.setNombres(nombresUsuario);
        usuario.setApellidos(apellidosUsuario);
        usuario.setGerencia(new Gerencia(Short.parseShort(gerenciaSeleccionado)));
        usuario.setCargo(new Cargo(Integer.parseInt(cargoSeleccionado)));
        usuario.setCiudad(new Ciudad(Integer.parseInt(ciudadSeleccionado)));
        usuario.setEmpresa(new Empresa(Integer.parseInt(companiaSeleccionado)));
        usuario.setCorreo(correoUsuario);
        usuario.setEstado(EstadoActividadEnum.INACTIVO.getId());
        usuario.setExtension(extension);
        usuario.setNumeroDocumento((long) numeroDocumentoUsuario);
        usuario.setTelefono(telefono);
        usuario.setTelefonoPersonal(telefonoPersonal);
        usuario.setTipoDocumento(new TipoDocumento(Integer.parseInt(tipoDocumentoSeleccionado)));
        usuario.setTipoEmpleado(new TipoEmpleado(Integer.parseInt(tipoEmpleadoSeleccionado)));
        usuario.setUsuario(usuario.getNombres() + usuario.getApellidos());
        usuario.setGrupoList(grupos);
        usuario.setActivo(EstadoActividadEnum.ACTIVO.getId());
        usuario.setUsername(usernameUsuario);

        if (tieneUsuarioRed == null) {
            tieneUsuarioRed = "1";
        }

        usuario.setUsuarioRed(tieneUsuarioRed.equals("1") ? (short) 1 : (short) 0);

        try {
            localAdminSol.crearUsuario(usuario, tieneUsuarioRed.equals("1"), idAdminSolicitudes);
            incluirMensaje(ResourceBundle.getBundle("mensajes").getString("usuarioCreadoOk"));
        } catch (ClaroException ex) {
            incluirMensaje(ex.getMessage());
        }

        borrarCampos();
    }

//++++++++++++++++++++++++++++++++ MÉTODOS PROPIOS DEL BEAN ++++++++++++++++++++++++
    /**
     * Método que llena una lista con los diferentes cargos que hay en la base
     * de datos
     */
    private void llenarCompanias() {
        List<Empresa> empresas;

        empresas = localDatabase.findEmpresaByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (companiasSelect == null) {
            companiasSelect = new ArrayList<SelectItem>();
        }

        for (Empresa temporal : empresas) {
            companiasSelect.add(new SelectItem(temporal.getIdEmpresa(), temporal.getNombre()));
        }
    }

    /**
     * Método que llena una lista con los diferentes cargos que hay en la base
     * de datos
     */
    private void llenarCargos() {
        List<Cargo> cargos;

        cargos = localDatabase.findCargoByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (cargosSelect == null) {
            cargosSelect = new ArrayList<SelectItem>();
        }

        for (Cargo temporal : cargos) {
            cargosSelect.add(new SelectItem(temporal.getIdCargo(), temporal.getNombre()));
        }
    }

    /**
     * Método que llena una lista con los diferentes tipos de empleados que hay
     * en la base de datos
     */
    private void llenarTipoEmpleados() {
        List<TipoEmpleado> tiposEmpleados;

        tiposEmpleados = localDatabase.findTipoEmpleadoByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (tipoEmpleadosSelect == null) {
            tipoEmpleadosSelect = new ArrayList<SelectItem>();
        }

        for (TipoEmpleado tipoEmpleado : tiposEmpleados) {
            if (tipoEmpleado.getIdTipoEmpleado() != TipoEmpleadoEnum.TEMPORAL.getId()) {
                tipoEmpleadosSelect.add(new SelectItem(tipoEmpleado.getIdTipoEmpleado(), tipoEmpleado.getNombre()));
            }
        }
    }

    /**
     * Método que llena una lista con los diferentes tipos de documentos que hay
     * en la base de datos
     */
    private void llenarTipoDocumentos() {
        List<TipoDocumento> tiposDocumentos;

        tiposDocumentos = localDatabase.findTipoDocumentoByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (tipoDocumentoSelect == null) {
            tipoDocumentoSelect = new ArrayList<SelectItem>();
        }

        for (TipoDocumento tipoDocumento : tiposDocumentos) {
            tipoDocumentoSelect.add(new SelectItem(tipoDocumento.getIdTipoDocumento(), tipoDocumento.getNombre()));
        }
    }

    /**
     * Método que llena una lista con las diferentes áreas que hay en la base de
     * datos
     */
    private void llenarAreas() {
        List<Gerencia> gerencias;

        gerencias = localDatabase.findGerenciaByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (gerenciasSelect == null) {
            gerenciasSelect = new ArrayList<SelectItem>();
        }

        for (Gerencia gerencia : gerencias) {
            gerenciasSelect.add(new SelectItem(gerencia.getIdGerencia(), gerencia.getNombre()));
        }
    }

    /**
     * Método que llena una lista con las diferentes ciudades que hay en la base
     * de datos
     */
    private void llenarCiudades() {
        List<Ciudad> ciudades;
        ciudades = localDatabase.findCiudadByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (ciudadesSelect == null) {
            ciudadesSelect = new ArrayList<SelectItem>();
        }

        for (Ciudad ciudad : ciudades) {
            ciudadesSelect.add(new SelectItem(ciudad.getIdCiudad(), ciudad.getNombre()));
        }
    }

    /**
     * Método que llena una lista con los diferentes grupos (roles) que hay en
     * la base de datos
     */
    private void llenarGrupos() {
        List<Grupo> grupos;
        grupos = localSeguridad.findGruposSinUsuarios(EstadoActividadEnum.ACTIVO);

        if (gruposSelect == null) {
            gruposSelect = new ArrayList<>();
        }

        for (Grupo grupo : grupos) {
            gruposSelect.add(new SelectItem(grupo.getIdGrupo(), grupo.getNombre()));
        }
    }

    /**
     * Método que toma un mensaje enviado y lo pasa al contexto para que sea
     * mostrado en la interfaz gráfica del usuario
     *
     * @param String, mensaje con el error que se desea mostrar.
     */
    private void incluirMensaje(String error) {
//        FacesContext.getCurrentInstance().addMessage(null, 
//            new FacesMessage(FacesMessage.SEVERITY_INFO, error, null));
        mensaje = error;
    }

    /**
     * Método que valida todos los campos, incluye el mensaje de error en el
     * contexto y retorna una respuesta dependiendo de los que encuentre en las
     * validaciones
     *
     * @return boolean, indicando si los campos del formulario son correctos o
     * no
     */
    private boolean isCamposInvalidos() {
        if (nombresUsuario == null || nombresUsuario.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorNombreUsuario");
            incluirMensaje(error);
            return true;
        }
        if (tipoEmpleadoSeleccionado == null || tipoEmpleadoSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorTipoEmpleado");
            incluirMensaje(error);
            return true;
        }
        if (apellidosUsuario == null || apellidosUsuario.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorApellidoUsuario");
            incluirMensaje(error);
            return true;
        }
        if (tipoDocumentoSeleccionado == null || tipoDocumentoSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorTipoDocumentoUsuario");
            incluirMensaje(error);
            return true;
        }
        if (numeroDocumentoUsuario == null || (numeroDocumentoUsuario <= 0)) {
            String error = ResourceBundle.getBundle("errores").getString("errorNumeroCedula");
            incluirMensaje(error);
            return true;
        }
        if (gerenciaSeleccionado == null || gerenciaSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorAreaUsuario");
            incluirMensaje(error);
            return true;
        }
        if (companiaSeleccionado == null || companiaSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorCompaniaUsuario");
            incluirMensaje(error);
            return true;
        }
        if (ciudadSeleccionado == null || ciudadSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorCiudadUsuario");
            incluirMensaje(error);
            return true;
        }
        if (correoUsuario == null || correoUsuario.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorCorreoUsuario");
            incluirMensaje(error);
            return true;
        }
        if (cargoSeleccionado == null || cargoSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorCargoUsuario");
            incluirMensaje(error);
            return true;
        }
        if (usernameUsuario != null && !usernameUsuario.isEmpty()) {
            if (localDatabase.findUsuarioByUsernameExacto(usernameUsuario) != null) {
                incluirMensaje(ResourceBundle.getBundle("errores").getString("errorUsuarioExistente"));
                return true;
            }
        }

        Pattern pattern = Pattern.compile(EMAIL_PATTERN);
        Matcher matcher;

        matcher = pattern.matcher(correoUsuario);
        if (!matcher.matches()) {
            String error = ResourceBundle.getBundle("errores").getString("errorCorreoIncorrecto");
            incluirMensaje(error);
            return true;
        }
        return false;
    }

    /**
     * Método que borra los campos cuando se han hecho modificaciones
     */
    private void borrarCampos() {
        usernameUsuario = null;
        tipoEmpleadoSeleccionado = null;
        tipoDocumentoSeleccionado = null;
        gerenciaSeleccionado = null;
        ciudadSeleccionado = null;
        cargoSeleccionado = null;
        nombresUsuario = null;
        apellidosUsuario = null;
        numeroDocumentoUsuario = null;
        companiaSeleccionado = null;
        correoUsuario = null;
        grupoSeleccionado = null;
        telefono = null;
        extension = null;
        telefonoPersonal = null;
        tieneUsuarioRed = null;
    }

    /**
     * ************************************** GETTERS Y SETTERS
     * ********************************
     */
    public List<SelectItem> getTipoEmpleadosSelect() {
        return tipoEmpleadosSelect;
    }

    public void setTipoEmpleadosSelect(List<SelectItem> tipoEmpleadosSelect) {
        this.tipoEmpleadosSelect = tipoEmpleadosSelect;
    }

    public List<SelectItem> getTipoDocumentoSelect() {
        return tipoDocumentoSelect;
    }

    public void setTipoDocumentoSelect(List<SelectItem> tipoDocumentoSelect) {
        this.tipoDocumentoSelect = tipoDocumentoSelect;
    }

    public List<SelectItem> getGerenciaSelect() {
        return gerenciasSelect;
    }

    public void setGerenciaSelect(List<SelectItem> areasSelect) {
        this.gerenciasSelect = areasSelect;
    }

    public List<SelectItem> getCiudadesSelect() {
        return ciudadesSelect;
    }

    public void setCiudadesSelect(List<SelectItem> ciudadesSelect) {
        this.ciudadesSelect = ciudadesSelect;
    }

    public List<SelectItem> getCargosSelect() {
        return cargosSelect;
    }

    public void setCargosSelect(List<SelectItem> cargosSelect) {
        this.cargosSelect = cargosSelect;
    }

    public String getTipoEmpleadoSeleccionado() {
        return tipoEmpleadoSeleccionado;
    }

    public void setTipoEmpleadoSeleccionado(String tipoEmpleadoSeleccionado) {
        this.tipoEmpleadoSeleccionado = tipoEmpleadoSeleccionado;
    }

    public String getTipoDocumentoSeleccionado() {
        return tipoDocumentoSeleccionado;
    }

    public void setTipoDocumentoSeleccionado(String tipoDocumentoSeleccionado) {
        this.tipoDocumentoSeleccionado = tipoDocumentoSeleccionado;
    }

    public String getGerenciaSeleccionado() {
        return gerenciaSeleccionado;
    }

    public void setGerenciaSeleccionado(String areaSeleccionado) {
        this.gerenciaSeleccionado = areaSeleccionado;
    }

    public String getCiudadSeleccionado() {
        return ciudadSeleccionado;
    }

    public void setCiudadSeleccionado(String ciudadSeleccionado) {
        this.ciudadSeleccionado = ciudadSeleccionado;
    }

    public String getCargoSeleccionado() {
        return cargoSeleccionado;
    }

    public void setCargoSeleccionado(String cargoSeleccionado) {
        this.cargoSeleccionado = cargoSeleccionado;
    }

    public String getNombresUsuario() {
        return nombresUsuario;
    }

    public void setNombresUsuario(String nombresUsuario) {
        this.nombresUsuario = nombresUsuario;
    }

    public String getApellidosUsuario() {
        return apellidosUsuario;
    }

    public void setApellidosUsuario(String apellidosUsuario) {
        this.apellidosUsuario = apellidosUsuario;
    }

    public Integer getNumeroDocumentoUsuario() {
        return numeroDocumentoUsuario;
    }

    public void setNumeroDocumentoUsuario(Integer numeroDocumentoUsuario) {
        this.numeroDocumentoUsuario = numeroDocumentoUsuario;
    }

    public List<SelectItem> getCompaniasSelect() {
        return companiasSelect;
    }

    public void setCompaniasSelect(List<SelectItem> companiasSelect) {
        this.companiasSelect = companiasSelect;
    }

    public String getCompaniaSeleccionado() {
        return companiaSeleccionado;
    }

    public void setCompaniaSeleccionado(String companiaSeleccionado) {
        this.companiaSeleccionado = companiaSeleccionado;
    }

    public String getCorreoUsuario() {
        return correoUsuario;
    }

    public void setCorreoUsuario(String correoUsuario) {
        this.correoUsuario = correoUsuario;
    }

    public List<SelectItem> getGerenciasSelect() {
        return gerenciasSelect;
    }

    public void setGerenciasSelect(List<SelectItem> gerenciasSelect) {
        this.gerenciasSelect = gerenciasSelect;
    }

    public List<SelectItem> getGruposSelect() {
        return gruposSelect;
    }

    public void setGruposSelect(List<SelectItem> gruposSelect) {
        this.gruposSelect = gruposSelect;
    }

    public String getGrupoSeleccionado() {
        return grupoSeleccionado;
    }

    public void setGrupoSeleccionado(String grupoSeleccionado) {
        this.grupoSeleccionado = grupoSeleccionado;
    }

    public String getTelefono() {
        return telefono;
    }

    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }

    public String getExtension() {
        return extension;
    }

    public void setExtension(String extension) {
        this.extension = extension;
    }

    public String getTelefonoPersonal() {
        return telefonoPersonal;
    }

    public void setTelefonoPersonal(String telefonoPersonal) {
        this.telefonoPersonal = telefonoPersonal;
    }

    public String getTieneUsuarioRed() {
        return tieneUsuarioRed;
    }

    public void setTieneUsuarioRed(String tieneUsuarioRed) {
        this.tieneUsuarioRed = tieneUsuarioRed;
    }

    public String getUsernameUsuario() {
        return usernameUsuario;
    }

    public void setUsernameUsuario(String usernameUsuario) {
        this.usernameUsuario = usernameUsuario;
    }

    public boolean isMostrarUsername() {
        return mostrarUsername;
    }

    public void setMostrarUsername(boolean mostrarUsername) {
        this.mostrarUsername = mostrarUsername;
    }

    public boolean isMostrarUsuarioRed() {
        return mostrarUsuarioRed;
    }

    public void setMostrarUsuarioRed(boolean mostrarUsuarioRed) {
        this.mostrarUsuarioRed = mostrarUsuarioRed;
    }

    public String getMensaje() {
        return mensaje;
    }

    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

}
